//===================================================================
// Date        : 2023-03-27
// Description : 
//
// Instantiation:
//  WCBB_AOMUX(__data_arr, __sel_in_oh0, __data_sel)
//  WCBB_BIN2ONEHOT(__bin_i, __onehot_o)
//  WCBB_ONEHOT2BIN(__onehot_i, __bin_o)
//  WCBB_PRIORITY_QUEUE_LSB(__vec_i, __onehot_o)
//  WCBB_PRIORITY_QUEUE_MSB(__vec_i, __onehot_o)
//  WCBB_NODE_1XN(__dest,                            
//               __valid_in , __ready_out, __info_in,
//               __valid_out, __ready_in , __info_out)
//  WCBB_NODE_NX1(__sel,              
//                __valid_in , __ready_out, __info_in,
//                __valid_out, __ready_in , __info_out)
//===================================================================

`ifndef __WING_CBB_DEFINE_MISC__
`define __WING_CBB_DEFINE_MISC__

//--------------------------------------------------//
//---------------------AOMUX------------------------//
//--------------------------------------------------//

`define WCBB_AOMUX(__data_arr, __sel_in_oh0, __data_sel) \
always_comb begin                                        \
  __data_sel = '0;                                       \
  for (int ii=0; ii < $bits(__sel_in_oh0); ii++) begin : g_``__data_sel \
    __data_sel = (__data_arr[ii] &                       \
                  {$bits(__data_sel){__sel_in_oh0[ii]}}) \
               | __data_sel;                             \
  end                                                    \
end         

//--------------------------------------------------//
//------------------bin2onehot----------------------//
//--------------------------------------------------//
`define WCBB_BIN2ONEHOT(__bin_i, __onehot_o)          \
for (genvar ii=0; ii<$bits(__onehot_o); ii++) begin : g_``__onehot_o \
  assign __onehot_o[ii] = (__bin_i==ii);            \
end                                       

//--------------------------------------------------//
//------------------onehot2bin----------------------//
//--------------------------------------------------//
`define WCBB_ONEHOT2BIN(__onehot_i, __bin_o)          \
always_comb begin                                     \
  localparam LOC_VEC_W = $bits(__onehot_i);           \
  localparam LOC_BIN_W = $bits(__bin_o);              \
  __bin_o = '0;                                       \
  for (int ii=0; ii < LOC_VEC_W; ii++) begin : g_``__bin_o      \
    __bin_o = ({LOC_BIN_W{__onehot_i[ii]}} & (LOC_BIN_W)'(ii)) \
            | __bin_o;                                \
  end                                                 \
end

//--------------------------------------------------//
//---------------Priority Queue LSB-----------------//
//--------------------------------------------------//
`define WCBB_PRIORITY_QUEUE_LSB(__vec_i, __onehot_o) \
always_comb begin                                  \
  logic [$bits(__vec_i)-1:0] __vec_adj_or;         \
                                                   \
  __vec_adj_or[0] = 1'b0;                          \
  for (int ii=1; ii<$bits(__vec_i); ii++) begin : g_``__onehot_o \
    __vec_adj_or[ii] = __vec_i     [ii-1] |        \
                      __vec_adj_or[ii-1] ;         \
  end                                              \
                                                   \
  __onehot_o = __vec_i & ~__vec_adj_or;            \
end

//--------------------------------------------------//
//---------------Priority Queue MSB-----------------//
//--------------------------------------------------//
`define WCBB_PRIORITY_QUEUE_MSB(__vec_i, __onehot_o) \
always_comb begin                                  \
  logic [$bits(__vec_i)-1:0] __vec_adj_or;         \
                                                   \
  __vec_adj_or[$bits(__vec_i)-1] = 1'b0;           \
  for (int ii=$bits(__vec_i)-2; ii>=0; ii--) begin : g_``__onehot_o \
    __vec_adj_or[ii] = __vec_i     [ii+1] |        \
                      __vec_adj_or[ii+1] ;         \
  end                                              \
                                                   \
  __onehot_o = __vec_i & ~__vec_adj_or;            \
end


`endif